import { defineStore } from "pinia";
import { ElMessage } from 'element-plus';
import request from "@/utils/request";

const localStorageKey = "hcoa-uploadLog";
const chunkSize = 1024 * 1024;

function getUploadLog() {
  let valueToReturn = [];
  let jsonStr = localStorage.getItem(localStorageKey);
  if (jsonStr) {
    valueToReturn = JSON.parse(jsonStr);
  }
  return valueToReturn;
}

function saveUploadLog(P_UploadLogList) {
  let saveData = [];
  P_UploadLogList.forEach((pre_item) => {
    let uploadLogItem = {
      url: pre_item.url, // 上传地址
      params: pre_item.params, // 上传参数
      fileName: pre_item.fileName, // 文件名称
      fileSize: pre_item.fileSize, // 文件大小
      progress: pre_item.progress, // 进度
      totalChunks: pre_item.totalChunks, // 总片数
      chunk: pre_item.chunk, // 已上传片数
      state: pre_item.state, // 状态 0 正在上传 1 暂停 2 上传完毕
      hash: pre_item.hash, // 上传记录唯一id
    };
    saveData.push(uploadLogItem);
  });
  localStorage.setItem(localStorageKey, JSON.stringify(saveData));
}

/**
 * 分片上传方法
 * @param {*} P_ChunkFile
 * @param {*} index
 * @param {*} totalChunks
 * @param {*} P_FileName
 * @param {*} P_Hash
 * @param {*} P_ChunkUrl
 * @param {*} P_Params
 * @param {*} P_OtherObj
 * @returns
 */
function uploadFileChunks(
  P_ChunkFile,
  index,
  totalChunks,
  P_FileName,
  P_Hash,
  P_ChunkUrl,
  P_Params
) {
  let formData = new FormData();
  formData.append("file", P_ChunkFile);
  P_Params["chunk"] = index;
  P_Params["chunks"] = totalChunks;
  P_Params["fileName"] = P_FileName;
  P_Params["hash"] = P_Hash;

  return request({
    url: P_ChunkUrl,
    method: "post",
    params: P_Params,
    data: formData,
    headers: {
      repeatSubmit: false,
      "Content-Type": "multipart/form-data",
    },
    noLoading: true, // 不显示加载
  });
}

export const useUploadLogStore = defineStore("uploadLog", {
  state: () => ({
    // 记录数据
    uploadLogList: getUploadLog(),
    // 是否显示上传悬浮视图
    isShowUploadFloatView: false,
  }),
  actions: {
    addLog(uploadLog) {
      this.uploadLogList.push(uploadLog);
      console.log("-----添加上传记录-------");
      console.log(this.uploadLogList);
      console.log("-----添加上传记录-------");
      saveUploadLog(this.uploadLogList);
    },
    stopUpload(P_Hash) {
      let findObj = this.uploadLogList.find((pre_item) => {
        return pre_item.hash == P_Hash;
      });
      if (findObj) {
        findObj.state = 1;
        saveUploadLog(this.uploadLogList);
      }
    },
    removeLog(P_Hash) {
      let findIndex = this.uploadLogList.findIndex((pre_item) => {
        return pre_item.hash == P_Hash;
      });
      if (findIndex > -1) {
        this.uploadLogList.splice(findIndex, 1);
        saveUploadLog(this.uploadLogList);
      }
    },
    starUpload(P_Hash) {
      let findObj = this.uploadLogList.find((pre_item) => {
        return pre_item.hash == P_Hash;
      });
      if (findObj != null) {
        const fileChunks = [];
        for (let i = 0; i < findObj.totalChunks; i++) {
          const start = i * chunkSize;
          const end = Math.min(findObj.file.size, start + chunkSize);
          const chunk = findObj.file.slice(start, end);
          fileChunks.push({
            chunk,
            start,
            end,
            index: i,
            totalChunks: findObj.totalChunks,
          });
        }
        let chunks = fileChunks.length;
        let chunk = findObj.chunk;

        const uploadChunk = () => {
          uploadFileChunks(
            fileChunks[chunk].chunk,
            chunk,
            chunks,
            findObj.fileName,
            findObj.hash,
            findObj.url,
            findObj.params
          ).then((res) => {
            chunk++;
            if (chunk < chunks) {
              if (findObj.state == 0) {
                findObj.chunk = chunk;
                findObj.progress = Math.floor((chunk * 100) / chunks);
                saveUploadLog(this.uploadLogList);
                uploadChunk();
              }
            } else {
              // 提示文件上传完毕
              findObj.chunk = chunks;
              findObj.progress = 100;
              findObj.state = 2; // 上传完毕
              this.removeLog(findObj.hash);
              ElMessage.success(findObj.fileName + ",已上传成功!");
            }
          });
        };
        uploadChunk();
      }
    },
    staruploadAsync(P_Hash) {
      return new Promise((resolve, reject) => {
        let findObj = this.uploadLogList.find((pre_item) => {
          return pre_item.hash == P_Hash;
        });
        if (findObj != null) {
          const fileChunks = [];
          for (let i = 0; i < findObj.totalChunks; i++) {
            const start = i * chunkSize;
            const end = Math.min(findObj.file.size, start + chunkSize);
            const chunk = findObj.file.slice(start, end);
            fileChunks.push({
              chunk,
              start,
              end,
              index: i,
              totalChunks: findObj.totalChunks,
            });
          }
          let chunks = fileChunks.length;
          let chunk = findObj.chunk;

          const uploadChunk = () => {
            uploadFileChunks(
              fileChunks[chunk].chunk,
              chunk,
              chunks,
              findObj.fileName,
              findObj.hash,
              findObj.url,
              findObj.params
            )
              .then((res) => {
                chunk++;
                if (chunk < chunks) {
                  if (findObj.state == 0) {
                    findObj.chunk = chunk;
                    findObj.progress = Math.floor((chunk * 100) / chunks);
                    saveUploadLog(this.uploadLogList);
                    uploadChunk();
                  }
                } else {
                  // 提示文件上传完毕
                  findObj.chunk = chunks;
                  findObj.progress = 100;
                  findObj.state = 2; // 上传完毕
                  this.removeLog(findObj.hash);
                  ElMessage.success(findObj.fileName + ",已上传成功!");
                  resolve(res);
                }
              })
              .catch((err) => {
                reject(err);
              });
          };
          uploadChunk();
        }
      });
    },
  },
});
